﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CityGatway;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using CityGateway.Objects;
using System.Configuration;
 

namespace CityGamePlay
{
    public class Cities : Dictionary<long, City>
    {

        private Dictionary<long, CityScore> m_Scores = null;
        public Dictionary<long, CityScore> Scores
        {
            get { return m_Scores; }
            set { m_Scores = value; }
        }

        public Dictionary<long, City> LifeCities { get { return this; } }

        public Cities() 
        {

          Scores = new Dictionary<long, CityScore>();
                //set up watcher
            FileSystemWatcher watcher = new FileSystemWatcher(ConfigurationSettings.AppSettings["CitiesFolder"], "city_*");
            watcher.Created += new FileSystemEventHandler(watcher_Created);
            watcher.Changed += new FileSystemEventHandler(watcher_Changed);
            watcher.EnableRaisingEvents = true;
       

        }

        void watcher_Changed(object sender, FileSystemEventArgs e)
        {
            FileStream fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read);
            BinaryFormatter bformatter = new BinaryFormatter();
            City city = (City)bformatter.Deserialize(fs);
          
            long uid = Convert.ToInt64(e.Name.Replace("city_", ""));

            city.CityStatus = this[uid].CityStatus;
            if (this.ContainsKey(uid))
                this[uid] = city;
            else
                this.Add(city.UserID, city);

            RateCity(city);

            fs.Close();
            fs.Dispose();
        }

        void watcher_Created(object sender, FileSystemEventArgs e)
        {

            FileStream fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read);
            BinaryFormatter bformatter = new BinaryFormatter();
            City city = (City)bformatter.Deserialize(fs);
            long uid = Convert.ToInt64( e.Name.Replace("city_", ""));
            if (this.ContainsKey(uid))
                this[uid] = city;
            else
                this.Add(city.UserID, city);


            RateCity(city);

            fs.Close();
            fs.Dispose();

        }





        public void LoadCities()
        {


            string[] cityFiles = Directory.GetFiles(ConfigurationSettings.AppSettings["CitiesFolder"], "city_*");

            this.Clear();
         
           foreach(string file in cityFiles)
           {
      
                FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
                BinaryFormatter bformatter = new BinaryFormatter();
                City  city = (City)bformatter.Deserialize(fs);
               this.Add(city.UserID, city);
                fs.Close();
                fs.Dispose();
           }



           foreach (City city in this.Values)
           {
               string file = ConfigurationSettings.AppSettings["CitiesFolder"] + "cityStatus_" + city.UserID.ToString();
               if (File.Exists(file))
               {

                   FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
                   BinaryFormatter bformatter = new BinaryFormatter();
                   CityStatus cityStatus = (CityStatus)bformatter.Deserialize(fs);
                   city.CityStatus = cityStatus;
                   fs.Close();
                   fs.Dispose();
               }
           }



           RateCities();

        }

        public void SaveCities()
        {
           List<City>  cities = this.Values.ToList();


            foreach(City city in cities)
            {

  

                //save only the status part

                string filepath = ConfigurationSettings.AppSettings["CitiesFolder"] +"cityStatus_" + city.UserID.ToString();
                
                FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate);
                
                BinaryFormatter bformatter = new BinaryFormatter();
                
                bformatter.Serialize(fs, city.CityStatus);

                fs.Close();
                fs.Dispose();

            }
        }

        public void RateCities()
        {
            foreach (City city in this.Values)
            {

                RateCity(city);
            }


        }



        public void RateCity(City city)
        {

                //recalculate city status
            CityScore score= new CityScore();

                //get all Zones

                int elemcount = city.Elements.Count;

                var res = (from a in city.Elements
                             where a.ElementType== CityElementType.Residential
                             select a).ToList();
                int rescount = 0;
                foreach (CityElement element in res)
                {
                    rescount += element.Capacity;
                }
                score.Residential = rescount;


                var jobs = (from a in city.Elements
                           where a.ElementType == CityElementType.Commercial || a.ElementType == CityElementType.Commercial 
                           select a).ToList();
                int jobcount = 0;

                foreach (CityElement element in jobs)
                {
                    jobcount += element.Capacity;
                }
                score.Jobs = jobcount;


                //foreach (CityElement elem in res)
                //{
                //    switch (elem.ElementSubType)
                //    {
                //        case CityElementSubType.Residential1:
                //            rescount += 20;
                //            break;
                //        case CityElementSubType.Residential2:
                //            rescount += 200;
                //            break;
                //        case CityElementSubType.Residential3:
                //            rescount += 2000;
                //            break;
                //    }
                //}

             
              


                //var com = (from a in city.Elements
                //           where a.ElementType == CityElementType.Commercial
                //           select a).ToList();

                //int comcount = 0;

                //foreach (CityElement elem in com)
                //{
                //    switch (elem.ElementSubType)
                //    {
                //        case CityElementSubType.Commercial1:
                //            rescount += 20;
                //            break;
                //        case CityElementSubType.Commercial2:
                //            rescount += 200;
                //            break;
                //        case CityElementSubType.Commercial3:
                //            rescount += 2000;
                //            break;
                //    }
                //}

                //var ind = (from a in city.Elements
                //           where a.ElementType == CityElementType.Industrial
                //           select a).ToList();



                //foreach (CityElement elem in ind)
                //{
                //    switch (elem.ElementSubType)
                //    {
                //        case CityElementSubType.Commercial1:
                //            rescount += 20;
                //            break;
                //        case CityElementSubType.Commercial2:
                //            rescount += 200;
                //            break;
                //        case CityElementSubType.Commercial3:
                //            rescount += 2000;
                //            break;
                //    }
                //}



            



                //var edu = (from a in city.Elements
                //           where a.ElementType == CityElementType.Education
                //           select a).ToList();


                //foreach (CityElement elem in edu)
                //{
                //    switch (elem.ElementSubType)
                //    {
                //        case CityElementSubType.Education1:
                //            rescount += 20;
                //            break;
                //        case CityElementSubType.Education2:
                //            rescount += 200;
                //            break;
                //        case CityElementSubType.Education3:
                //            rescount += 2000;
                //            break;
                //    }
                //}


                var health = (from a in city.Elements
                           where a.ElementType == CityElementType.HealthCare
                           select a).ToList();

                var sec = (from a in city.Elements
                           where a.ElementType == CityElementType.Police
                           select a).ToList();


                if (!Scores.ContainsKey(city.UserID))
                    Scores.Add(city.UserID, score);
                else
                    Scores[city.UserID] = score;

                city.CityStatus.CityScore = score;

            
        }


     


    }
}
